#include <math.h>
#include "Bolt.h"
#include "Aqua.h"
#include "Clash.h"
#include "classinventory.h"
#include "Lahan.h"
#include "player.h"
#include <iostream>

using namespace std;

Bolt::Bolt()
{
    SetX(3); //inisiasi lokasi x
    SetY(4); //inisiasi lokasi y
    SetChase(3,4); //inisiasi lokasi tanaman yang menjadi target
    SetTarget(0); //inisasi perintah kurcaci mengejar tanaman
    SetHoldCode(0); // inisiasi barang yang dipegang
    CommandHold(0); // inisiasi agar Bolt tidak memegang barang
    Sleep(); //menidurkan kurcaci
}

Bolt::Bolt(const Bolt& Ax)
{
    Position NewP = Ax.GetChase();

    SetX(Ax.GetX());
    SetY(Ax.GetY());
    SetChase(NewP.x,NewP.y);
    if (Ax.IsTargetting())
    {  SetTarget(1);}
    else {SetTarget(0);}

    if(Ax.IsWakeUp())
    {WakeUp();}
    else {Sleep();}

    if(Ax.IsHolding())
    { CommandHold(1);
    SetHoldCode(Ax.GetHoldCode());
    }
    else
    {
        CommandHold(0);
        SetHoldCode(0);
    }

}

Bolt::~Bolt()
{}


void Bolt::HomingTanaman()
{
    boolean IsGet = false;
    int i,j;

    i = -1;
    j = -1;

    while((i<= 1) && (IsGet == false ) )
    {
        j = -1;
        while((j <= 1) && (IsGet == false ) )
        {
            if(L.getStatus(GetX()+i,GetY()+j)== 7)
            { SetChase(GetX()+i,GetY()+j); //menyimpan posisi tanaman tersebut di variabel Chase
            SetTarget(1); //memerintahkan kurcaci untuk mengejar tanaman
            IsGet = true;}
            else j++;
        }
		i++;
    }


}

boolean Bolt::IsSafeToWalk(int Ax, int Ay)
{
int stats;
    Position pemain;

    stats = (L.getStatus(Ax,Ay)); //mengambil posisi lahan
    pemain = (P.GetPosition()); //mengambil posisi pemain
    //mengambil kurcaci lain? setelah ini ditambahkan
    if ( 
            (stats == 5) || (stats == 6) || (stats == 7) || (stats == 8) ||// lahan tak memungkinkan untuk diakses
            (pemain.x == Ax && pemain.y == Ay) /* memeriksa posisi pemain*/|| (C.GetX() == Ax && C.GetY() == Ay) || (A.GetX() == Ax && A.GetY() == Ay)
            ||(Ax>8)||(Ax<0)//keluar dari batas x
            ||(Ay>8)||(Ay<0)//keluar dari batas y
            ||((Ay == 0) &&(Ax == 8 ) )//menginjak kotak penjualan
            )
    {return false;}
    else
        return true;

}

void Bolt::ActKurcaci()
{
     
    //Dieksekusi jika kondisi sudah memenuhi (target sesuai dengan kriteria, ada di sebelah tanaman)
    Position NewP = GetChase();
    SetHoldCode(L.getTanaman(NewP.x,NewP.y).GetKodeTanaman()); //mengambil kode tanaman
    L.getTanaman(NewP.x,NewP.y).Harvested(); 
    SetTarget(0);
    CommandHold(1);
}

void Bolt::CommandHold(int Ax)
{
    if(Ax == 0)
    {Holding = false;}
    else if (Ax == 1)
    {Holding = true;}
}

void Bolt::SetHoldCode(int Ax)
{
    HoldCode = Ax;
}

int Bolt::GetHoldCode() const
{
    return HoldCode;
}

void Bolt::ToTheBox() //Untuk bergerak ke kotak penjualan, Bolt bisa menembus segala rintangan :D
{
    int RandomInt; //nilai dari random integer
    int Aman; //bernilai 0 untuk penahan, bernilai 1 supaya kurcaci dapat mengeksekusi gerakannya.
	
    int xbox = 8;
    int ybox = 0;
    int Fx = GetX();
    int Fy = GetY();
	
	if ( (Fx == (xbox - 1) && Fy == ybox) || (Fx == xbox && Fy == (ybox + 1)) ) //berada tepat di sebelah kotak jual
    {
        SellHold();
    }
	
    //Algoritma : Apabila si Bolt sudah ada di pinggir, dia akan bergerak  ke Box
	

    else if(Fy == 1 && Fx != 8 && Fx != 0) //Kalau posisi si Bolt ada tepat di bawah Pinggiran atas
    {
        if(IsSafeToWalk(Fx,Fy-1))
        {SetY(Fy-1);}
    }
    else if(Fy == 7 && Fx != 8 && Fx != 0) //Kalau posisi si Bolt ada tepat di atas Pinggiran bawah, tapi bukan di pinggir kiri atau kanan.
    {
		if(IsSafeToWalk(Fx,Fy+1))
         {SetY(Fy+1);}
    }
    else if(Fx == 1 && Fy != 0 && Fy != 8) //Kalau posisi si Bolt ada tepat di kanan pinggiran kiri
    {
        if(IsSafeToWalk((Fx-1),Fy))
        {SetX(Fx-1);}
    }
    else if(Fx == 7 && Fy != 0 && Fy != 8) //Kalau posisi si Bolt ada tepat di kiri pinggiran kanan
    {
        if(IsSafeToWalk((Fx+1),Fy))
        {SetX(Fx+1);}
    }
	else if (Fy == 0)
	{
		if(IsSafeToWalk((Fx+1),Fy))
        {SetX(Fx+1);}
	}
	else if (Fx == 8)
	{
		if(IsSafeToWalk(Fx,(Fy-1)))
        {SetY(Fy-1);}
	}
	else if (Fy == 8 && Fx < 8)
	{
		if(IsSafeToWalk((Fx+1),Fy))
        {SetX(Fx+1);}
	}
	else if (Fx == 0 && Fy < 8 && Fy > 5)
	{
		if(IsSafeToWalk(Fx,(Fy+1)))
        {SetY(Fy+1);}
	}
	else if ( (Fx == 0 && Fy > 0 && Fy <= 5))
	{
		if(IsSafeToWalk(Fx,(Fy-1)))
        {SetY(Fy-1);}
	}
    else //Kalau tidak? ya random.
    {
            RandomInt = GenRandom();
              /*
                    dengan asumsi:
                    1 = utara
                    2 = timur
                    3 = selatan
                    4 = barat
              */
            Aman = 0;
            do{
                    //Proses ini akan mengakses method dari map, yang menunjukkan posisi ujung dari map.
                    switch (RandomInt) {
                    case 1 :
                                    if ( (Fy - 1) >= 0 /*batas atas Map*/ )
                                    {
                                        if(IsSafeToWalk(Fx, (Fy - 1) ) == false) /* Pengecekan apakah posisi tersebut aman untuk dimasuki. sengaja tidak di && dengan pengecekan diatas, untuk mencegah terjadinya error */
                                        {
                                          RandomInt = GenRandom();
                                          Aman = 0;
                                        }
                                        else
                                            Aman = 1;
                                    }
                                    else
                                            { RandomInt = GenRandom(); Aman = 0; }
                                    break;

                    case 2 :
                                    if ( (Fx + 1) <=  8   /*batas kanan Map*/ )
                                    {
                                        if(IsSafeToWalk((Fx + 1), Fy ) == false)
                                        {
                                          RandomInt = GenRandom();
                                          Aman = 0;
                                        }
                                        else
                                            Aman = 1;
                                    }
                                     else
                                            { RandomInt = GenRandom(); Aman = 0; }
                                    break;

                    case 3 :
                                    if ( (Fy + 1) <= 8 /*batas bawah Map*/ )
                                    {
                                        if (IsSafeToWalk(Fx, (Fy + 1) ) == false)
                                        {
                                           RandomInt = GenRandom();
                                           Aman = 0;
                                        }
                                        else
                                            Aman = 1;
                                    }
                                      else
                                            {RandomInt = GenRandom(); Aman = 0;}
                                    break;

                    case 4 :
                                    if ( (Fx - 1) >= 0 /*batas kiri Map*/ )
                                    {
                                        if(IsSafeToWalk((Fx - 1), Fy ) == false)
                                        {
                                          RandomInt = GenRandom();
                                          Aman = 0;
                                        }
                                        else
                                            Aman = 1;
                                    }
                                    else { RandomInt = GenRandom(); Aman = 0; }
                                    break;
                            }
              }
              while (Aman == 0);

              //proses dibawah dieksekusi bila  Aman = 1

              switch (RandomInt)
              {
                    case 1 : {
                                    SetY(Fy - 1);
                                    break;
                            }

                    case 2 : {
                                    SetX(Fx + 1);
                                    break;
                            }
                    case 3 : {
                                    SetY(Fy + 1);
                                    break;
                            }
                    case 4 : {
                                    SetX(Fx - 1);
                                    break;
                            }
              }
    }
}

void Bolt::Move()
{
	//Tahap pertama dari method move adalah mengambil satu arah random dan memeriksanya.
	int RandomInt; //nilai dari random integer
	int Aman; //bernilai 0 untuk penahan, bernilai 1 supaya kurcaci dapat mengeksekusi gerakannya.
	
        int Fx, Fy; // penampung posisi kurcaci
        Aman = 0;

        Fx = GetX();
        Fy = GetY();
	
        if (IsHolding()) // kalau si Bolt memegang tanaman hasi panen
        { ToTheBox();}
        else if (IsTargetting())
            { 
				ChaseTarget();
				}
	else
	{
            RandomInt = GenRandom();
              /*
                    dengan asumsi:
                    1 = utara
                    2 = timur
                    3 = selatan
                    4 = barat
              */
            Aman = 0;
            do{
                    //Proses ini akan mengakses method dari map, yang menunjukkan posisi ujung dari map.
                    switch (RandomInt) {
                    case 1 :
                                    if ( (Fy - 1) >= 0 /*batas atas Map*/ )
                                    {
                                        if(IsSafeToWalk(Fx, (Fy - 1) ) == false) /* Pengecekan apakah posisi tersebut aman untuk dimasuki. sengaja tidak di && dengan pengecekan diatas, untuk mencegah terjadinya error */
                                        {
                                          RandomInt = GenRandom();
                                          Aman = 0;
                                        }
                                        else
                                            Aman = 1;
                                    }
                                    else
                                            { RandomInt = GenRandom(); Aman = 0; }
                                    break;

                    case 2 :
                                    if ( (Fx + 1) <=  8   /*batas kanan Map*/ )
                                    {
                                        if(IsSafeToWalk((Fx + 1), Fy ) == false)
                                        {
                                          RandomInt = GenRandom();
                                          Aman = 0;
                                        }
                                        else
                                            Aman = 1;
                                    }
                                     else
                                            { RandomInt = GenRandom(); Aman = 0; }
                                    break;

                    case 3 :
                                    if ( (Fy + 1) <= 8 /*batas bawah Map*/ )
                                    {
                                        if (IsSafeToWalk(Fx, (Fy + 1) ) == false)
                                        {
                                           RandomInt = GenRandom();
                                           Aman = 0;
                                        }
                                        else
                                            Aman = 1;
                                    }
                                      else
                                            {RandomInt = GenRandom(); Aman = 0;}
                                    break;

                    case 4 :
                                    if ( (Fx - 1) >= 0 /*batas kiri Map*/ )
                                    {
                                        if(IsSafeToWalk((Fx - 1), Fy ) == false)
                                        {
                                          RandomInt = GenRandom();
                                          Aman = 0;
                                        }
                                        else
                                            Aman = 1;
                                    }
                                    else { RandomInt = GenRandom(); Aman = 0; }
                                    break;
                            }
              }
              while (Aman == 0);

              //proses dibawah dieksekusi bila  Aman = 1

              switch (RandomInt)
              {
                    case 1 : {
                                    SetY(Fy - 1);
                                    break;
                            }

                    case 2 : {
                                    SetX(Fx + 1);
                                    break;
                            }
                    case 3 : {
                                    SetY(Fy + 1);
                                    break;
                            }
                    case 4 : {
                                    SetX(Fx - 1);
                                    break;
                            }
              }
                    //proses dibawah digunakan untuk meng-scan-tanaman

                 HomingTanaman(); // didefinisikan di kelas anak
        }
}

void Bolt::SellHold()
{
    I.ChangeMoney(I.GetPrice(GetHoldCode()));
    CommandHold(0);//Menandakan bahwa si kurcaci sudah nggak memegang apa - apa lagi.
}
boolean Bolt::IsHolding() const
{
    return Holding;
}




